package ntd.remote.link;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.Opt;
import cn.hutool.json.JSONUtil;
import lj.a.protocol.lj.bean.LJProtocolInfo;
import lj.netty.ToolNettyInit;
import lj.netty.bean.LJNettyInitContext;
import lj.netty.bean.LJNettyMsgContext;
import lj.netty.listen.LJNettyListen;
import ntd.action.ActionManager;
import ntd.action.bo.ActionInBo;
import ntd.action.bo.ActionInfo;
import ntd.action.bo.ActionOutBo;
import ntd.remote.link.bo.MsgBO;
import ntd.remote.link.bo.RemoteBO;
import ntd.tool.abnormal.ComAbnormal;

public class ComRegistryServer {

    private static LJNettyInitContext ljNettyInitContext;

    public static LJNettyListen ljNettyListen;

    public static void init(RemoteBO remoteBO) {
        ljNettyInitContext = new LJNettyInitContext().setPort(39100).setLJCNettyListen(ljNettyListen = new LJNettyListen() {
            @Override
            public byte[] onLjMsg(LJNettyMsgContext ljNettyMsgContext) {
                return remoteBO.getFunIn().accept(MsgBO.transform(ljNettyMsgContext));
            }
        });

        new ToolNettyInit(ljNettyInitContext).start();
    }

    public static LJNettyMsgContext sendMsg(MsgBO msgBO) {
        LJProtocolInfo ljProtocolInfo = new LJProtocolInfo();
        ljProtocolInfo.setBytes(msgBO.getBytes());
        msgBO.setBytes(new byte[]{});
        ljProtocolInfo.setData(JSONUtil.toJsonStr(msgBO).getBytes());
        return ljNettyListen.pushMsg(msgBO.getNetCode(), ljProtocolInfo);
    }

    public static void run() {
        RemoteBO remoteBO = new RemoteBO();

        remoteBO.setFunIn(msgBO -> {
            ActionInfo actionInfo = Opt.ofNullable(ActionManager.get(msgBO.getActionCode())).orElseThrow(() -> new ComAbnormal("找不到Action[{}]", msgBO.getActionCode()));
            ActionOutBo actionOutBo = actionInfo.getAction().execute(new ActionInBo().setData(Dict.parse(msgBO)));
            return actionOutBo.toBytes();
        });

        ComRegistryServer.init(remoteBO);
    }

    public static void main(String[] args) {
        run();
    }
}
